<!DOCTYPE html>
<html>
<head>
  <title>Physics Diagram</title>
  <style>
    canvas {
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="450" height="400"></canvas>
  <script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // Parameters
    const cx = 160;
    const cy = 200;
    const R = 90;
    const mainLineWidth = 2;

    // --- Define Semi-circle Path ---
    ctx.beginPath();
    ctx.arc(cx, cy, R, Math.PI / 2, 3 * Math.PI / 2);
    ctx.closePath(); // This adds the straight diameter line to the path

    // --- Draw Hatching (Shading) using Clip ---
    ctx.save();
    ctx.clip(); // Use the path above as a clipping mask

    const lineSpacing = 6;
    ctx.lineWidth = 1;
    ctx.strokeStyle = 'black';
    // Draw vertical lines that cover the clipped area
    for (let x = cx - R; x <= cx; x += lineSpacing) {
      ctx.beginPath();
      ctx.moveTo(x, cy - R - 5);
      ctx.lineTo(x, cy + R + 5);
      ctx.stroke();
    }
    ctx.restore(); // Remove the clipping mask

    // --- Draw Semi-circle Outline on top of the hatching ---
    ctx.lineWidth = mainLineWidth;
    ctx.strokeStyle = 'black';
    ctx.stroke(); // Strokes the path defined earlier

    // --- Draw Center Point 'O' ---
    ctx.beginPath();
    ctx.arc(cx, cy, 3.5, 0, 2 * Math.PI);
    ctx.fillStyle = 'black';
    ctx.fill();

    // --- Draw Labels 'O' and '2R' ---
    ctx.fillStyle = 'black';
    ctx.font = 'italic 24px "Times New Roman"';
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillText('O', cx + 12, cy);

    const dimX = cx + R + 40;
    ctx.fillText('2R', dimX + 15, cy);

    // --- Draw Dimension Line ---
    ctx.lineWidth = 1.5;
    const arrowSize = 10;
    const yTop = cy - R;
    const yBottom = cy + R;
    const tickWidth = 20;

    // Vertical line
    ctx.beginPath();
    ctx.moveTo(dimX, yTop);
    ctx.lineTo(dimX, yBottom);
    ctx.stroke();

    // Top Tick
    ctx.beginPath();
    ctx.moveTo(dimX - tickWidth / 2, yTop);
    ctx.lineTo(dimX + tickWidth / 2, yTop);
    ctx.stroke();
    
    // Bottom Tick
    ctx.beginPath();
    ctx.moveTo(dimX - tickWidth / 2, yBottom);
    ctx.lineTo(dimX + tickWidth / 2, yBottom);
    ctx.stroke();
    
    // Top Arrow (pointing inwards)
    ctx.beginPath();
    ctx.moveTo(dimX, yTop);
    ctx.lineTo(dimX - 5, yTop + arrowSize);
    ctx.moveTo(dimX, yTop);
    ctx.lineTo(dimX + 5, yTop + arrowSize);
    ctx.stroke();

    // Bottom Arrow (pointing inwards)
    ctx.beginPath();
    ctx.moveTo(dimX, yBottom);
    ctx.lineTo(dimX - 5, yBottom - arrowSize);
    ctx.moveTo(dimX, yBottom);
    ctx.lineTo(dimX + 5, yBottom - arrowSize);
    ctx.stroke();

    // --- Draw Bottom Caption ---
    ctx.font = '22px "KaiTi", "SimSun", sans-serif'; // Use Chinese-friendly fonts
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    const figureCenterX = (cx - R + dimX) / 2;
    ctx.fillText('习题 8-17 图', figureCenterX, 380);

  </script>
</body>
</html>